﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Net;
using System.Xml;

using System.ServiceModel;
using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Services;
using Microsoft.Xrm.Client.Configuration;
using Microsoft.Xrm.Portal;
using Microsoft.Xrm;

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Crm.Services.Utility;

namespace CRM2ORCH
{
    public class Get
    {
        public OrganizationService service;
        public string message = string.Empty;

        public string getEntityByGuid(String entity, String objectGuid)
        {
            try
            {
                Connection conn = new Connection();
                service = conn.setConnection();
                Guid guid = new Guid(objectGuid);
                List<string> values = new List<string>();
                values.Add("<Entity name=\"" + entity + "\">");
                Entity oggettoCrm = (Entity)service.Retrieve(entity, guid, new ColumnSet(allColumns: true));
                //message = message + oggettoCrm.FormattedValues + " -- " + oggettoCrm.LogicalName + " -- " + oggettoCrm.FormattedValues.Count + " -- " + oggettoCrm.Attributes + " -- " + oggettoCrm.Attributes.Count;

                values.Add("<" + entity + " guid=" + "\"" + guid + "\">");
                foreach (var value in oggettoCrm.Attributes)
                {
                    String key = value.Key;
                    String cleanValue = value.Value.ToString();
                    String type = value.Value.GetType().ToString();

                    //checking for unformatted values
                    if (type.Equals("Microsoft.Xrm.Sdk.OptionSetValue"))
                    {
                        foreach (var findValue in oggettoCrm.FormattedValues)
                        {
                            if (findValue.Key.Equals(key))
                            {
                                cleanValue = findValue.Value;
                            }
                        }
                    }
                    if (type.Equals("Microsoft.Xrm.Sdk.EntityReference"))
                    {
                        cleanValue = ((EntityReference)oggettoCrm[key]).Name;
                        type = ((EntityReference)oggettoCrm[key]).LogicalName;
                    }
                    //end of checks
                    values.Add("<Attribute key=\"" + key + "\" value=\"" + cleanValue + "\" type=\"" + type + "\"></Attribute>");
                }
                values.Add("</" + entity + ">");

                values.Add("</Entity>");

                foreach (var item in values)
                {
                    message = message + item + Environment.NewLine;

                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return message;
        }

        public string getEntityAttributes(String entity)
        {
            message = string.Empty;
            //
            try
            {
                Connection conn = new Connection();
                service = conn.setConnection();
                QueryExpression q = new QueryExpression();

                q.EntityName = entity;
                //q.Criteria = "";

                // Create the ConditionExpression.
                ConditionExpression conditionAccount = new ConditionExpression();

                RetrieveEntityRequest req = new RetrieveEntityRequest();

                req.EntityFilters = EntityFilters.Attributes;
                req.LogicalName = entity;
                req.RetrieveAsIfPublished = true;

                RetrieveEntityResponse resp = (RetrieveEntityResponse)service.Execute(req);
                List<string> list = new List<string>();
                List<string> attribute = new List<string>();
                attribute.Add("<" + entity + ">");
                foreach (var attr in resp.EntityMetadata.Attributes)
                {
                    String name = "";
                    String type = "";
                    String label = "";

                    try
                    {
                        name = attr.LogicalName;
                    }
                    catch (Exception e)
                    {
                        name = "NotAvailable";
                    }
                    try
                    {
                        type = attr.AttributeType.ToString();
                    }
                    catch (Exception e)
                    {
                        type = "NotAvailable";
                    }
                    try
                    {
                        label = attr.DisplayName.UserLocalizedLabel.Label;
                    }
                    catch (Exception e)
                    {
                        label = "NotAvailable";
                    }


                    //attribute.Add("<Attribute>" + attr.EntityLogicalName + "   " + attr.Description + "    " + attr.LogicalName + "    "+attr.AttributeType+"    "+attr.MetadataId+"</Attribute>");
                    attribute.Add("<Attribute name=\"" + name + "\" type=\"" + type + "\" label=\"" + label + "\"></Attribute>");
                }

                attribute.Add("</" + entity + ">");
                foreach (var item in attribute)
                {
                    message = message + item + Environment.NewLine;

                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }
            //NEW_MOTIVOCONTATTOMACRO nome:MICROSOFT.XRM.SDK.LABEL

            //returns the message
            return message;
        }
        public string getEntities(String entityName, String attributeName, String filter)
        {
            try
            {
                Connection conn = new Connection();
                service = conn.setConnection();
                //Guid userid = ((WhoAmIResponse)service.Execute(new WhoAmIRequest())).UserId;
                String entity = entityName;
                QueryExpression q = new QueryExpression();

                q.EntityName = entity;
                //q.Criteria = "";

                // Create the ConditionExpression.
                ConditionExpression conditionAccount = new ConditionExpression();

                // Set the ConditionExpressions Properties 
                conditionAccount.AttributeName = attributeName;
                conditionAccount.Operator = ConditionOperator.Equal;
                conditionAccount.Values.Add(filter);

                // Create the FilterExpression.
                FilterExpression filterAccount = new FilterExpression();

                // Set the properties of the FilterExpression.
                filterAccount.FilterOperator = LogicalOperator.And;
                filterAccount.Conditions.Add(conditionAccount);

                if (!attributeName.Equals(""))
                {
                    if (!filter.Equals(""))
                    {
                        q.Criteria = filterAccount;
                    }
                }
                //q.ColumnSet.AddColumn("");

                EntityCollection coll = service.RetrieveMultiple(q);
                List<string> values = new List<string>();
                values.Add("<Entity name=\"" + entityName + "\">");
                for (int i = 0; i < coll.Entities.Count; i++)
                {
                    Entity yourEntity = coll[i];

                    Guid guid = new Guid(yourEntity.Id + "");
                    Entity oggettoCrm = (Entity)service.Retrieve(entity, guid, new ColumnSet(allColumns: true));
                    //message = message + oggettoCrm.FormattedValues + " -- " + oggettoCrm.LogicalName + " -- " + oggettoCrm.FormattedValues.Count + " -- " + oggettoCrm.Attributes + " -- " + oggettoCrm.Attributes.Count;

                    values.Add("<" + entityName + " guid=" + "\"" + guid + "\">");
                    foreach (var value in oggettoCrm.Attributes)
                    {
                        String key = value.Key;
                        String cleanValue = value.Value.ToString();
                        String type = value.Value.GetType().ToString();

                        //checking for unformatted values
                        if (type.Equals("Microsoft.Xrm.Sdk.OptionSetValue"))
                        {
                            foreach (var findValue in oggettoCrm.FormattedValues)
                            {
                                if (findValue.Key.Equals(key))
                                {
                                    cleanValue = findValue.Value;
                                }
                            }
                        }
                        if (type.Equals("Microsoft.Xrm.Sdk.EntityReference"))
                        {
                            cleanValue = ((EntityReference)oggettoCrm[key]).Name;
                            type = ((EntityReference)oggettoCrm[key]).LogicalName;
                        }
                        //end of checks

                        values.Add("<Attribute key=\"" + key + "\" value=\"" + cleanValue + "\" type=\"" + type + "\"></Attribute>");
                    }
                    values.Add("</" + entityName + ">");
                }
                values.Add("</Entity>");

                foreach (var item in values)
                {
                    message = message + item + Environment.NewLine;

                }

            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return message;
        }
        public string getAllEntities()
        {
            try
            {
                Connection conn = new Connection();
                service = conn.setConnection();
                RetrieveAllEntitiesRequest req = new RetrieveAllEntitiesRequest();
                req.EntityFilters = EntityFilters.Attributes;
                req.RetrieveAsIfPublished = true;

                RetrieveAllEntitiesResponse resp = (RetrieveAllEntitiesResponse)service.Execute(req);
                List<string> list = new List<string>();
                List<string> attribute = new List<string>();
                attribute.Add("<Entities>");
                foreach (var item in resp.EntityMetadata)
                {

                    attribute.Add("<Entity><LogicalName>" + item.LogicalName + "</LogicalName><DisplayName>" + item.DisplayName + "</DisplayName><ID>" + item.MetadataId + "</id></Entity>");

                }
                attribute.Add("</Entities>");
                attribute.Sort();
                foreach (var item in attribute)
                {
                    message = message + item + Environment.NewLine;

                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return message;
        }

    }
}